# Copyright 2020 Intel Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# For files generated by the protobuf compiler
include_directories(${P4C_BINARY_DIR}/control-plane)

################ Proto
set (DPDK_P4RUNTIME_DIR ${CMAKE_CURRENT_SOURCE_DIR}/control-plane/proto)
set (DPDK_P4RUNTIME_INFO_PROTO ${DPDK_P4RUNTIME_DIR}/p4info.proto)
set (DPDK_P4RUNTIME_INFO_GEN_SRCS ${P4C_BINARY_DIR}/control-plane/p4/config/dpdk/p4info.pb.cc)
set (DPDK_P4RUNTIME_INFO_GEN_HDRS ${P4C_BINARY_DIR}/control-plane/p4/config/dpdk/p4info.pb.h)
# The generated code for protobuf has an excessive number of warnings
set_source_files_properties(${DPDK_P4RUNTIME_INFO_GEN_SRCS} PROPERTIES
  COMPILE_FLAGS "-Wno-unused-parameter")

add_custom_target (dpdk_runtime_dir
  ${CMAKE_COMMAND} -E make_directory
  ${P4C_BINARY_DIR}/control-plane/p4/config/dpdk)
# Generate source code from .proto using protoc. The output is
# placed in the build directory inside `control-plane` directory
add_custom_command(
    OUTPUT ${DPDK_P4RUNTIME_INFO_GEN_SRCS} ${DPDK_P4RUNTIME_INFO_GEN_HDRS}
  COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
    --proto_path ${DPDK_P4RUNTIME_DIR}
    --proto_path ${P4C_SOURCE_DIR}/control-plane/p4runtime/proto
    --cpp_out ${P4C_BINARY_DIR}/control-plane/p4/config/dpdk
    --python_out ${P4C_BINARY_DIR}/control-plane/p4/config/dpdk
          ${DPDK_P4RUNTIME_INFO_PROTO}
  DEPENDS ${DPDK_P4RUNTIME_INFO_PROTO} dpdk_runtime_dir
  COMMENT "Generating protobuf files for p4info on target DPDK."
  )

add_library(dpdk_runtime STATIC ${DPDK_P4RUNTIME_INFO_GEN_SRCS})
set_source_files_properties (${DPDK_P4RUNTIME_INFO_GEN_SRCS} PROPERTIES GENERATED TRUE)

set(P4C_DPDK_SOURCES
    ../bmv2/common/lower.cpp
    backend.cpp
    main.cpp
    midend.cpp
    dpdkHelpers.cpp
    dpdkProgram.cpp
    dpdkProgramStructure.cpp
    dpdkArch.cpp
    dpdkContext.cpp
    dpdkAsmOpt.cpp
    options.cpp
    control-plane/bfruntime_ext.cpp
    )

set(P4C_DPDK_HEADERS
    ../bmv2/common/lower.h
    backend.h
    midend.h
    dpdkCheckExternInvocation.h
    dpdkHelpers.h
    dpdkProgram.h
    dpdkArch.h
    dpdkContext.h
    constants.h
    dpdkAsmOpt.h
    printUtils.h
    dpdkProgramStructure.h
    options.h
    control-plane/bfruntime_ext.h
    control-plane/bfruntime_arch_handler.h
    )

set (IR_DEF_FILES ${IR_DEF_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/dpdk.def PARENT_SCOPE)

set(DPDK_IR_SRCS
    spec.cpp
    printUtils.cpp
    dbprint-dpdk.cpp
    )
# IR sources that need to go into the frontend library
set(QUAL_DPDK_IR_SRCS)
foreach(src IN LISTS DPDK_IR_SRCS)
    set(QUAL_DPDK_IR_SRCS ${QUAL_DPDK_IR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${src})
endforeach()
set(EXTENSION_FRONTEND_SOURCES ${EXTENSION_FRONTEND_SOURCES} ${QUAL_DPDK_IR_SRCS} PARENT_SCOPE)

add_cpplint_files(${CMAKE_CURRENT_SOURCE_DIR} "${P4C_DPDK_SOURCES}" "${P4C_DPDK_HEADERS}" "${DPDK_IR_SRCS}")
add_executable(p4c-dpdk ${P4C_DPDK_SOURCES})
target_link_libraries (p4c-dpdk dpdk_runtime ${P4C_LIBRARIES} ${P4C_LIB_DEPS})
add_dependencies(p4c-dpdk dpdk_runtime genIR frontend)

install (TARGETS p4c-dpdk
        RUNTIME DESTINATION ${P4C_RUNTIME_OUTPUT_DIRECTORY})

add_custom_target(linkp4cdpdk
        COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_BINARY_DIR}/p4c-dpdk ${P4C_BINARY_DIR}/p4c-dpdk
        )

add_dependencies(p4c_driver linkp4cdpdk)

set(DPDK_COMPILER_DRIVER "${CMAKE_CURRENT_SOURCE_DIR}/run-dpdk-test.py")

set (P4_16_SUITES
  "${P4C_SOURCE_DIR}/testdata/p4_16_samples/psa-*.p4"
  "${P4C_SOURCE_DIR}/testdata/p4_16_samples/pna-*.p4")
p4c_add_tests("dpdk" ${DPDK_COMPILER_DRIVER} "${P4_16_SUITES}" "" "--bfrt")

include(DpdkXfail.cmake)
